/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.bpm.api.runtime.task;

import com.je.bpm.model.task.payloads.*;
import com.je.bpm.model.task.result.TaskListResult;
import com.je.bpm.model.task.result.TaskResult;
import com.je.bpm.runtime.shared.operator.validator.PayloadValidErrorException;
import com.je.bpm.runtime.task.TaskOperatorService;
import com.je.bpm.runtime.task.operator.*;

import java.util.Date;
import java.util.List;

public class TaskOperatorServiceImpl implements TaskOperatorService {

    private TaskCancelDelegateOperator taskCancelDelegateOperator;
    private TaskChangeAssigneeOperator taskChangeAssigneeOperator;
    private TaskClaimOperator taskClaimOperator;
    private TaskDelayOperator taskDelayOperator;
    private TaskDelegateOperator taskDelegateOperator;
    private TaskDirectSendOperator taskDirectSendOperator;
    private TaskDismissOperator taskDismissOperator;
    private TaskGobackOperator taskGobackOperator;
    private TaskPassRoundOperator taskPassRoundOperator;
    private TaskPassRoundReadOperator taskPassRoundReadOperator;
    private TaskRetreiveOperator taskRetreiveOperator;
    private TaskSubmitOperator taskSubmitOperator;
    private TaskTransferOperator taskTransferOperator;
    private TaskUrgeOperator taskUrgeOperator;
    private TaskPassOperator taskPassOperator;
    private TaskVetoOperator taskVetoOperator;
    private TaskAbstainOperator taskAbstainOperator;
    private TaskRebookOperator taskRebookOperator;
    private TaskCountersignReductionOperator taskCountersignReductionOperator;
    private TaskCountersignAddSignatureOperator taskCountersignAddSignatureOperator;
    private TaskPersonnelAdjustmentsOperator taskPersonnelAdjustmentsOperator;

    public TaskOperatorServiceImpl(TaskCancelDelegateOperator taskCancelDelegateOperator, TaskChangeAssigneeOperator taskChangeAssigneeOperator,
                                   TaskClaimOperator taskClaimOperator, TaskDelayOperator taskDelayOperator,
                                   TaskDelegateOperator taskDelegateOperator, TaskDirectSendOperator taskDirectSendOperator,
                                   TaskDismissOperator taskDismissOperator, TaskGobackOperator taskGobackOperator,
                                   TaskPassRoundOperator taskPassRoundOperator, TaskPassRoundReadOperator taskPassRoundReadOperator,
                                   TaskRetreiveOperator taskRetreiveOperator, TaskSubmitOperator taskSubmitOperator,
                                   TaskTransferOperator taskTransferOperator, TaskUrgeOperator taskUrgeOperator, TaskPassOperator taskPassOperator,
                                   TaskVetoOperator taskVetoOperator, TaskAbstainOperator taskAbstainOperator,
                                   TaskRebookOperator taskRebookOperator, TaskCountersignReductionOperator taskCountersignReductionOperator,
                                   TaskCountersignAddSignatureOperator taskCountersignAddSignatureOperator, TaskPersonnelAdjustmentsOperator taskPersonnelAdjustmentsOperator) {
        this.taskCancelDelegateOperator = taskCancelDelegateOperator;
        this.taskChangeAssigneeOperator = taskChangeAssigneeOperator;
        this.taskClaimOperator = taskClaimOperator;
        this.taskDelayOperator = taskDelayOperator;
        this.taskDelegateOperator = taskDelegateOperator;
        this.taskDirectSendOperator = taskDirectSendOperator;
        this.taskDismissOperator = taskDismissOperator;
        this.taskGobackOperator = taskGobackOperator;
        this.taskPassRoundOperator = taskPassRoundOperator;
        this.taskPassRoundReadOperator = taskPassRoundReadOperator;
        this.taskRetreiveOperator = taskRetreiveOperator;
        this.taskSubmitOperator = taskSubmitOperator;
        this.taskTransferOperator = taskTransferOperator;
        this.taskUrgeOperator = taskUrgeOperator;
        this.taskPassOperator = taskPassOperator;
        this.taskVetoOperator = taskVetoOperator;
        this.taskAbstainOperator = taskAbstainOperator;
        this.taskRebookOperator = taskRebookOperator;
        this.taskCountersignReductionOperator = taskCountersignReductionOperator;
        this.taskCountersignAddSignatureOperator = taskCountersignAddSignatureOperator;
        this.taskPersonnelAdjustmentsOperator = taskPersonnelAdjustmentsOperator;
    }

    @Override
    public TaskListResult submit(String prod, String piid, String beanId, String taskId, String assignee, String comment) throws PayloadValidErrorException {
        return taskSubmitOperator.operate(TaskSubmitPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignee(assignee)
                .setComment(comment));
    }

    @Override
    public TaskListResult submit(String prod, String piid, String beanId, String taskId, String assignee, String comment, String target) throws PayloadValidErrorException {
        return taskSubmitOperator.operate(TaskSubmitPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignee(assignee)
                .setComment(comment)
                .setTarget(target));
    }

    @Override
    public TaskListResult submit(String prod, String piid, String beanId, String taskId, String assignee, String comment, String target, String nodeId) throws PayloadValidErrorException {
        return taskSubmitOperator.operate(TaskSubmitPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignee(assignee)
                .setComment(comment)
                .setTarget(target)
                .setNodeId(nodeId));
    }

    @Override
    public TaskResult pass(String prod, String piid, String beanId, String taskId, String comment) throws PayloadValidErrorException {
        return taskPassOperator.operate(TaskPassPayload.build().build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setComment(comment));
    }

    @Override
    public TaskResult veto(String prod, String piid, String beanId, String taskId, String comment) throws PayloadValidErrorException {
        return taskVetoOperator.operate(TaskVetoPayload.build().build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setComment(comment));
    }

    @Override
    public TaskResult abstain(String prod, String piid, String beanId, String taskId, String comment) throws PayloadValidErrorException {
        return taskAbstainOperator.operate(TaskAbstainPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setComment(comment));
    }

    @Override
    public TaskResult rebook(String prod, String piid, String beanId, String taskId, String comment, TaskRebookPayload.RebookTypeEnum rebookTypeEnum) throws PayloadValidErrorException {
        return taskRebookOperator.operate(TaskRebookPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setComment(comment)
                .setOpinionType(rebookTypeEnum));
    }

    @Override
    public TaskResult countersignAddSignature(String prod, String piid, String beanId, String taskId, String assignee) throws PayloadValidErrorException {
        return taskCountersignAddSignatureOperator.operate(TaskCountersignAddSignaturePayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignee(assignee)
        );
    }

    @Override
    public TaskResult personnelAdjustments(String prod, String piid, String beanId, String taskId, String assignees) throws PayloadValidErrorException {
        return taskPersonnelAdjustmentsOperator.operate(TaskPersonnelAdjustmentsPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignees(assignees)
        );
    }

    @Override
    public TaskResult countersignReduction(String prod, String piid, String beanId, String taskId, String assignee) throws PayloadValidErrorException {
        return taskCountersignReductionOperator.operate(TaskCountersignReductionPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignee(assignee)
        );
    }

    @Override
    public TaskResult delegate(String prod, String piid, String beanId, String taskId, String assignee, String comment) throws PayloadValidErrorException {
        return taskDelegateOperator.operate(TaskDelegatePayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignee(assignee)
                .setComment(comment));
    }

    @Override
    public TaskResult cancelDelegate(String prod, String piid, String beanId, String taskId) throws PayloadValidErrorException {
        return taskCancelDelegateOperator.operate(TaskCancelDelegatePayload.build()
                .setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId));
    }

    @Override
    public TaskResult changeAssignee(String prod, String piid, String beanId, String taskId, String assignee) throws PayloadValidErrorException {
        return taskChangeAssigneeOperator.operate(TaskChangeAssigneePayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId)
                .setAssignee(assignee));
    }

    @Override
    public TaskResult claim(String prod, String piid, String beanId, String taskId) throws PayloadValidErrorException {
        return taskClaimOperator.operate(TaskClaimPayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId));
    }

    @Override
    public TaskResult delay(String prod, String piid, String beanId, String taskId) throws PayloadValidErrorException {
        return taskDelayOperator.operate(TaskDelayPayload.build().setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId));
    }

    @Override
    public TaskResult delay(String prod, String piid, String beanId, String taskId, Date dueDate) throws PayloadValidErrorException {
        return taskDelayOperator.operate(TaskDelayPayload.build().setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId).setDueDate(dueDate));
    }

    @Override
    public TaskResult taskDirectSend(String prod, String piid, String beanId, String taskId) throws PayloadValidErrorException {
        return taskDirectSendOperator.operate(TaskDirectSendPayload.build().setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId));
    }

    @Override
    public TaskResult dismiss(String prod, String piid, String beanId, String taskId, String targetDefinitionKey, String comment) throws PayloadValidErrorException {
        return taskDismissOperator.operate(TaskDismissPayload.build()
                .setProd(prod).setPiid(piid)
                .setBeanId(beanId).setTaskId(taskId)
                .setTargetDefinitionKey(targetDefinitionKey)
                .setComment(comment));
    }

    @Override
    public TaskResult goback(String prod, String piid, String beanId, String taskId, String comment) throws PayloadValidErrorException {
        return taskGobackOperator.operate(TaskGobackPayload.build().setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId).setComment(comment));
    }

    @Override
    public TaskResult passround(String prod, String piid, String beanId, String taskId, List<String> assigneeList) throws PayloadValidErrorException {
        return taskPassRoundOperator.operate(TaskPassRoundPayload.build().setProd(prod)
                .setPiid(piid).setBeanId(beanId).setTaskId(taskId));
    }

    @Override
    public TaskResult passroundRead(String prod, String piid, String beanId, String taskId) throws PayloadValidErrorException {
        return taskPassRoundReadOperator.operate(TaskPassRoundReadePayload.build()
                .setProd(prod)
                .setPiid(piid)
                .setBeanId(beanId)
                .setTaskId(taskId));
    }

    @Override
    public TaskResult passroundRead(String prod, String piid, String beanId, String taskId, String assignee) throws PayloadValidErrorException {
        return taskPassRoundReadOperator.operate(TaskPassRoundReadePayload.build()
                .setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId).setAssignee(assignee));
    }

    @Override
    public TaskResult retrieve(String prod, String piid, String beanId, String taskId) throws PayloadValidErrorException {
        return taskRetreiveOperator.operate(TaskRetrievePayload.build().setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId));
    }

    @Override
    public TaskResult transfer(String prod, String piid, String beanId, String taskId, String assignee) throws PayloadValidErrorException {
        return taskTransferOperator.operate(TaskTransferPayload.build()
                .setProd(prod).setPiid(piid).setBeanId(beanId).setTaskId(taskId).setAssignee(assignee));
    }

}
